Revert "GtkWindow: Move cairo_save/restore from marshaller"
authorAlexander Larsson <alexl@redhat.com>
Tue, 18 Jun 2013 09:11:14 +0000 (11:11 +0200)
committerAlexander Larsson <alexl@redhat.com>
Tue, 18 Jun 2013 09:32:18 +0000 (11:32 +0200)
This reverts commit 6c7689506f8b6c71522e6c8a25a2b4523641592c.

This is not right as we need to save/restore around *each*
callback, not just each emission.

gtk/gtkwidget.c

index c78522f762b10e375517a9f5178879fce258a4c3..9626c800f39797f4a4ea7f5ef201df1f9e763465 100644 (file)
@@ -953,6 +953,64 @@ child_property_notify_dispatcher (GObject     *object,
   GTK_WIDGET_GET_CLASS (object)->dispatch_child_properties_changed (GTK_WIDGET (object), n_pspecs, pspecs);
 }
 
+/* We guard against the draw signal callbacks modifying the state of the
+ * cairo context by surounding it with save/restore.
+ * Maybe we should also cairo_new_path() just to be sure?
+ */
+static void
+gtk_widget_draw_marshaller (GClosure     *closure,
+                            GValue       *return_value,
+                            guint         n_param_values,
+                            const GValue *param_values,
+                            gpointer      invocation_hint,
+                            gpointer      marshal_data)
+{
+  cairo_t *cr = g_value_get_boxed (&param_values[1]);
+
+  cairo_save (cr);
+
+  _gtk_marshal_BOOLEAN__BOXED (closure,
+                               return_value,
+                               n_param_values,
+                               param_values,
+                               invocation_hint,
+                               marshal_data);
+
+
+  cairo_restore (cr);
+}
+
+static void
+gtk_widget_draw_marshallerv (GClosure     *closure,
+                            GValue       *return_value,
+                            gpointer      instance,
+                            va_list       args,
+                            gpointer      marshal_data,
+                            int           n_params,
+                            GType        *param_types)
+{
+  cairo_t *cr;
+  va_list args_copy;
+
+  G_VA_COPY (args_copy, args);
+  cr = va_arg (args_copy, gpointer);
+
+  cairo_save (cr);
+
+  _gtk_marshal_BOOLEAN__BOXEDv (closure,
+                               return_value,
+                               instance,
+                               args,
+                               marshal_data,
+                               n_params,
+                               param_types);
+
+
+  cairo_restore (cr);
+
+  va_end (args_copy);
+}
+
 static void
 gtk_widget_class_init (GtkWidgetClass *klass)
 {
@@ -1900,12 +1958,12 @@ G_GNUC_END_IGNORE_DEPRECATIONS
                   G_TYPE_FROM_CLASS (gobject_class),
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GtkWidgetClass, draw),
-                  _gtk_boolean_handled_accumulator, NULL,
-                 _gtk_marshal_BOOLEAN__BOXED,
+                   _gtk_boolean_handled_accumulator, NULL,
+                   gtk_widget_draw_marshaller,
                   G_TYPE_BOOLEAN, 1,
-                  CAIRO_GOBJECT_TYPE_CONTEXT | G_SIGNAL_TYPE_STATIC_SCOPE);
+                  CAIRO_GOBJECT_TYPE_CONTEXT);
   g_signal_set_va_marshaller (widget_signals[DRAW], G_TYPE_FROM_CLASS (klass),
-                             _gtk_marshal_BOOLEAN__BOXEDv);
+                              gtk_widget_draw_marshallerv);
 
   /**
    * GtkWidget::mnemonic-activate:
@@ -6337,14 +6395,10 @@ _gtk_widget_draw_internal (GtkWidget *widget,
     {
       gboolean result;
 
-      cairo_save (cr);
-
       g_signal_emit (widget, widget_signals[DRAW],
                      0, cr,
                      &result);
 
-      cairo_restore (cr);
-
 #ifdef G_ENABLE_DEBUG
       if (G_UNLIKELY (gtk_get_debug_flags () & GTK_DEBUG_BASELINES))
        {